<?php
namespace App\Handlers;

use App;
use App\Jobs\SendHeartBeat;
use App\Services\Product\CRC16;
use App\Services\Product\DeviceService;
use Cache;
use Carbon\Carbon;
use Exception;
use Illuminate\Foundation\Bus\DispatchesJobs;

class SwooleHandler{
	use DispatchesJobs;

	private $_heartBeatData;

	public function _construct(){
		
	}

	/**
	 * tcp 连接开始
	 * @param  [type] $serv 
	 * @return [type]       
	 */
	public function onStart($serv){

	}

	/**
	 * tcp 连接
	 * @param  [type] $serv    
	 * @param  [type] $fd      
	 * @param  [type] $from_id 
	 * @return [type]          
	 */
	public function onConnect($serv, $fd, $from_id){
		try{
			$this->_heartBeatData = pack("v5C3V2v", 0x00bb, 0x0006, 0x0000, 0x000D, 0x0002, 0x12, 0x00, 0x00, 0X00000000, 0X00000000, 0x4FE5);
			
			if($serv->connection_info($fd)['server_port'] == env('WEB_PORT'))
			{
		       	$job = (new SendHeartBeat($fd))->delay(3)->onQueue('heartBeat');
		       	$this->dispatch($job);
			}
			
		}catch(Exception $e){
			logger(['SwooleHandler@onConnect' => [
				'line' => $e->getLine(),
				'message' => $e->getMessage(),
				]]);
		}
	}

	/**
	 * tcp 连接接受到消息
	 * @param  [type] $serv    
	 * @param  [type] $fd      
	 * @param  [type] $from_id 
	 * @param  [type] $data    
	 * @return [type]          
	 */
	public function onReceive($serv, $fd, $from_id, $data){
		try{
			if(strlen($data) >= 30){
		    	$result = CRC16::check(substr($data, 4, strlen($data) - 6), substr($data, strlen($data) - 2));
			}else{
				$result = false;
			}
		    
		    if($result){
		    	$u = unpack("v5dat",$data);
	            $flag       = $u["dat1"];
	            $cmd        = $u["dat2"];
	            $cmd_status = $u["dat3"];
	            $datalen    = $u["dat4"];
	            $dataCmd    = $u["dat5"];
	            
	            if($flag == 0xbb && $cmd == 0x8007 && $datalen == 46){
	                (new DeviceService())->handle($dataCmd, $fd, $data);
	                $this->cacheFds($serv);
	            }

				$serv->send($fd, $this->_heartBeatData);
		    }
		}catch(Exception $e){
			logger(['SwooleHandler@onReceive' => [
				'line' => $e->getLine(),
				'message' => $e->getMessage(),
				]]);
		}
	}

	/**
	 * tcp 关闭
	 * @param  [type] $serv    
	 * @param  [type] $fd      
	 * @param  [type] $from_id 
	 * @return [type]          
	 */
	public function onClose($serv, $fd, $from_id){
		// echo "close -> fd:$fd, from_id:$from_id\n";
		$this->cacheFds($serv);
	}

	public function cacheFds($serv)
	{
		$fds = [];
		foreach($serv->connections as $fd) {
			$fds[] = $fd;
		}
		Cache::put('fds', $fds, Carbon::now()->addMinutes(60));
	}
	

}